local skel = fk.CreateSkill {
  name = "lb__yuekuang",
}

Fk:loadTranslationTable {
  ["lb__yuekuang"] = "月狂",
  [":lb__yuekuang"] = "每回合限两次，当你的体力值与手牌数相等时，你可选择一项并依次执行其邻项，然后于下次发动此技能后执行本次选择项：" ..
      "1.倒置额定阶段；2.与另一项合并；3.摸两张牌；4.失去1点体力；5.与另一项互换。",
  -- 年度牛马大作
  -- 额定阶段：准备阶段、判定阶段、摸牌阶段、出牌阶段、弃牌阶段、结束阶段。
  -- 若额定阶段本回合被跳过，则不计入以下的额定阶段。
  -- 倒置状态/一回合第一次倒置：取消你本回合剩余的额定阶段，依次获得你本回合执行过的额定阶段。
  -- 一回合第二次倒置：取消你以上获得的额定阶段，按额定阶段顺序获得你当前阶段之后的额定阶段。
  ["#lb__yuekuang_1"] = "倒置额定阶段",
  ["#lb__yuekuang_2"] = "与另一项合并",
  ["#lb__yuekuang_3"] = "摸两张牌",
  ["#lb__yuekuang_4"] = "失去1点体力",
  ["#lb__yuekuang_5"] = "与另一项互换",

  ["@lb__yuekuang"] = "",
  ["@@lb__yuekuang_reverse"] = "阶段倒置",

  ["#lb__yuekuang"] = "月狂：你可以选择一项并依次执行其邻项，然后于下次发动此技能后执行本次选择项",
  ["#lb__yuekuang_insert"] = "月狂：请将 第 %arg 项与另一项合并",
  ["#lb__yuekuang_change"] = "月狂：请将 第 %arg 项与另一项交换",

  ["#lb__yuekuang_log"] = "月狂：%from选择了第%arg项",
  ["#GainAnRulePhase"] = "%from 开始进行额定的 %arg",
}

local changeMark = function(player)
  local lang = { "倒", "合", "摸", "失", "换" }
  local mark = table.concat(table.map(player:getTableMark(skel.name), function(choices, index)
    local list = table.concat(table.map(choices, function(name)
      if player:getMark(skel.name .. "_reverse") > 0 and name == 1 then
        --return "<font color='red'>" .. lang[name] .. "</font>" --颜色会覆盖，还是改字吧
        return "正"
      end
      return lang[name]
    end))
    if player:getMark(skel.name .. "_end") == index then
      return "<font color='#0598BC'>" .. list .. "</font>"
    end
    return list
  end), "/")
  player.room:setPlayerMark(player, "@lb__yuekuang", mark)
end

local yuekuang_spec = {
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local list = {}
    for _, choices in ipairs(player:getTableMark(skel.name)) do
      local choice = table.concat(table.map(choices, function(name)
        return Fk:translate("#lb__yuekuang_" .. name)
      end), "，然后")
      table.insert(list, choice)
    end
    table.insert(list, "Cancel")
    local choice = room:askToChoice(player, {
      choices = list,
      skill_name = skel.name,
      prompt = "#lb__yuekuang",
    })
    if choice ~= "Cancel" then
      event:setCostData(self, { index = table.indexOf(list, choice) })
      return true
    end
  end,
  ---@param player ServerPlayer
  on_use = function(self, event, target, player, data)
    local room = player.room
    local index = event:getCostData(self).index            -- 此次选择的项
    local end_index = player:getMark(skel.name .. "_end")  -- 上次选择的项
    room:setPlayerMark(player, skel.name .. "_end", index) -- 记录此次选择的项，在下次发动触发
    local effect_index = { index - 1, index + 1 }
    if end_index > 0 then
      table.insert(effect_index, end_index)
    end
    room:sendLog {
      type = "#lb__yuekuang_log",
      from = player.id,
      arg = index,
      toast = true,
    }
    while #effect_index > 0 do
      local list = player:getTableMark(skel.name)
      local num = effect_index[1]
      if list[num] then
        local effect_list = table.simpleClone(list[num]) --此项效果固定，执行完成前不因选项变动而更改
        for _, choice in ipairs(effect_list) do
          if player.dead then return end                 --角色死亡，不再执行
          list = player:getTableMark(skel.name)          -- 构式插结
          if choice == 1 then
            --倒置阶段
            room:setPlayerMark(player, skel.name .. "_reverse", player:getMark(skel.name .. "_reverse") > 0 and 0 or 1)
            local current_turn = room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
            if current_turn and room:getCurrent() == player then
              current_turn.data.extra_data = current_turn.data.extra_data or {}
              if player:getMark(skel.name .. "_reverse") == 0 then -- 回正阶段
                if current_turn.data.extra_data.lb__yuekuang_phase_list then
                  local phase_list = current_turn.data.extra_data.lb__yuekuang_phase_list
                  local current_phase = room.logic:getEventsByRule(GameEvent.Phase, 1, function(e)
                    local phase = e.data
                    return phase.who == player and phase.reason == "game_rule" and not phase.skipped
                  end, nil, Player.HistoryTurn)
                  if #current_phase == 1 then
                    local begin = table.indexOf(phase_list, current_phase[1].data.phase)
                    if begin > 0 then
                      phase_list = table.slice(phase_list, begin + 1)
                    end
                  end
                  for i = #current_turn.data.phase_table, current_turn.data.phase_index + 1, -1 do
                    local phase_data = current_turn.data.phase_table[i]
                    if phase_data.who == player and phase_data.reason == "game_rule" then
                      table.remove(current_turn.data.phase_table, i)
                    end
                  end
                  for i = #phase_list, 1, -1 do
                    table.insert(current_turn.data.phase_table, current_turn.data.phase_index + 1,
                      {
                        who = player,
                        reason = "game_rule",
                        phase = phase_list[i],
                      })
                  end
                end
              else --倒置阶段
                -- 执行过的额定阶段
                local phase_list_reverse = {}
                local current_phase = room.logic:getCurrentEvent():findParent(GameEvent.Phase, true)
                room.logic:getEventsByRule(GameEvent.Phase, 999, function(e)
                  local phase = e.data
                  if phase.who == player and phase.reason == "game_rule" and not phase.skipped
                      and (not current_phase or current_phase.id ~= e.id) then
                    table.insert(phase_list_reverse, phase.phase)
                  end
                end, nil, Player.HistoryTurn)
                local phase_list = table.reverse(phase_list_reverse)
                for i, phase in ipairs(current_turn.data.phase_table) do
                  if i >= current_turn.data.phase_index and phase.who == player and phase.reason == "game_rule" and not phase.skipped then
                    table.insert(phase_list, phase.phase) -- 本回合额定阶段，由已执行和未执行组成
                  end
                end
                current_turn.data.extra_data.lb__yuekuang_phase_list = phase_list
                for i = #current_turn.data.phase_table, current_turn.data.phase_index + 1, -1 do
                  local phase = current_turn.data.phase_table[i]
                  if phase.who == player and phase.reason == "game_rule" and not phase.skipped then
                    table.remove(current_turn.data.phase_table, i)
                  end
                end
                for i = #phase_list_reverse, 1, -1 do
                  table.insert(current_turn.data.phase_table, current_turn.data.phase_index + 1,
                    {
                      who = player,
                      reason = "game_rule",
                      phase = phase_list_reverse[i],
                    })
                end
              end
            end
          elseif (choice == 2 or choice == 5) and list[num] and #list > 1 then
            local list_insert = {} -- 所有可以合并或交换的选项
            local ask = {}
            for _, c in ipairs(list) do
              local ch = table.concat(table.map(c, function(name)
                return Fk:translate("#lb__yuekuang_" .. name)
              end), "，然后")
              table.insert(list_insert, ch)
              table.insert(ask, ch)
            end
            table.remove(list_insert, num)
            if #list_insert > 0 then
              --选择的另一项
              local cho = room:askToChoice(player, {
                choices = list_insert,
                all_choices = ask,
                skill_name = skel.name,
                prompt = (choice == 2 and "#lb__yuekuang_insert" or "#lb__yuekuang_change") .. ":::" .. num
              })
              local cho_num = table.indexOf(ask, cho)
              if cho_num and cho_num >= 1 and cho_num <= #list then
                if choice == 2 then -- 合并
                  table.insertTable(list[cho_num], list[num])
                  table.remove(list, num)
                else
                  list[num], list[cho_num] = list[cho_num], list[num] --交换
                end
              end
            end
            room:setPlayerMark(player, skel.name, list)
          elseif choice == 3 then
            player:drawCards(2, skel.name)
          elseif choice == 4 then
            room:loseHp(player, 1, skel.name)
          end
          changeMark(player)
        end
      end
      table.remove(effect_index, 1)
    end
  end,
}

skel:addEffect(fk.HpChanged, {
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(skel.name) and player:getHandcardNum() == player.hp
        and player:usedSkillTimes(skel.name) < 2
  end,
  on_cost = yuekuang_spec.on_cost,
  on_use = yuekuang_spec.on_use,
})

skel:addEffect(fk.AfterCardsMove, {
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(skel.name) and player:usedSkillTimes(skel.name) < 2
        and player:getHandcardNum() == player.hp then
      for _, move in ipairs(data) do
        if (move.from == player and table.find(move.moveInfo, function(info)
              return info.fromArea == Card.PlayerHand
            end)) or (move.to == player and move.toArea == Card.PlayerHand) then
          return true
        end
      end
    end
  end,
  on_cost = yuekuang_spec.on_cost,
  on_use = yuekuang_spec.on_use,
})

skel:addEffect(fk.TurnStart, {
  global = true,
  can_refresh = function(self, event, target, player, data)
    return target == player and data.reason == "game_rule" and not data.turn_end
        and player:hasSkill(skel.name, true) and player:getMark(skel.name .. "_reverse") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local current_turn = room.logic:getCurrentEvent()
    if current_turn then
      local phase_list_reverse = {}
      local current_phase = room.logic:getCurrentEvent():findParent(GameEvent.Phase, true)
      room.logic:getEventsByRule(GameEvent.Phase, 999, function(e)
        local phase = e.data
        if phase.who == player and phase.reason == "game_rule" and not phase.skipped
            and (not current_phase or current_phase.id ~= e.id) then
          table.insert(phase_list_reverse, phase.phase)
        end
      end, nil, Player.HistoryTurn)
      local phase_list = table.reverse(phase_list_reverse)
      for i, phase in ipairs(current_turn.data.phase_table) do
        if i >= current_turn.data.phase_index and phase.who == player and phase.reason == "game_rule" and not phase.skipped then
          table.insert(phase_list, phase.phase)           -- 本回合额定阶段，由已执行和未执行组成
        end
      end
      current_turn.data.extra_data = current_turn.data.extra_data or {}
      current_turn.data.extra_data.lb__yuekuang_phase_list = phase_list
      for i = #current_turn.data.phase_table, current_turn.data.phase_index + 1, -1 do
        local phase = current_turn.data.phase_table[i]
        if phase.who == player and phase.reason == "game_rule" and not phase.skipped then
          table.remove(current_turn.data.phase_table, i)
        end
      end
      for i = #phase_list_reverse, 1, -1 do
        table.insert(current_turn.data.phase_table, current_turn.data.phase_index + 1,
          {
            who = player,
            reason = "game_rule",
            phase = phase_list_reverse[i],
          })
      end
    end
  end,
})

--[[
skel:addEffect(fk.EventPhaseChanging, {
  global = true,
  can_refresh = function(self, event, target, player, data)
    return target == player and data.reason == "game_rule" and not data.skipped
        and player:hasSkill(skel.name, true)
  end,
  on_refresh = function(self, event, target, player, data)
    local logic = player.room.logic
    local Turn = logic:getEventsByRule(GameEvent.Turn, 1, function(e)
      return true
    end, 0)
    if #Turn > 0 then
      Turn = Turn[1]
    else
      return
    end
    if Turn then
      Turn.data.extra_data = Turn.data.extra_data or {}
      if player:getMark(skel.name .. "_reverse") > 0 then
        local list = Turn.data.extra_data.lb__yuekuang_list or {}
        if #list == 0 then
          logic:getEventsByRule(GameEvent.Phase, 999, function(e)
            local phase = e.data
            if phase.who == player and phase.reason == "game_rule" and not phase.skipped then
              table.insert(list, phase.phase)
            end
          end, nil, Player.HistoryTurn)
          local current = table.remove(list, 1) -- 还没进阶段，取不了当前的阶段id，顺序是反的，直接去掉第一个
          Turn.data.extra_data.lb__yuekuang_list = list
          if not Turn.data.extra_data.lb__yuekuang_phase_list then
            local phase_list = { current }
            for i, phase in ipairs(Turn.data.phase_table) do
              if i >= Turn.data.phase_index and phase.who == player and phase.reason == "game_rule" then
                table.insert(phase_list, phase.phase)
              end
            end
            Turn.data.extra_data.lb__yuekuang_phase_list = phase_list
          end
        end
        Turn.data.extra_data.lb__yuekuang = (Turn.data.extra_data.lb__yuekuang or 0) + 1
        local num = Turn.data.extra_data.lb__yuekuang
        if list[num] then
          data.phase = list[num]
        else
          Turn.data.turn_end = true
        end
      else
        local list = Turn.data.extra_data.lb__yuekuang_phase_list or {}
        if #list > 0 then
          Turn.data.extra_data.lb__yuekuang_phase_list_num = (Turn.data.extra_data.lb__yuekuang_phase_list_num or 0) + 1
          local num = Turn.data.extra_data.lb__yuekuang_phase_list_num
          if list[num] then
            data.phase = list[num]
          else
            Turn.data.turn_end = true
          end
        end
      end
      --data = reverse
      if Turn.data.turn_end then return end
      player.room:sendLog {
        type = "#GainAnRulePhase",
        from = player.id,
        arg = Util.PhaseStrMapper(data.phase),
      }
    end
  end,
})
--]]
skel:addAcquireEffect(function(self, player, is_start)
  local list = {}
  for i = 1, 5, 1 do
    table.insert(list, { i })
  end
  player.room:setPlayerMark(player, skel.name, list)
  changeMark(player)
  --[[
  if player:getMark(skel.name .. "_reverse") > 0 then
    player.room:setPlayerMark(player, "@@lb__yuekuang_reverse", 0)
  end
  --]]
end)

skel:addLoseEffect(function(self, player, is_death)
  player.room:setPlayerMark(player, skel.name, 0)
  player.room:setPlayerMark(player, "@lb__yuekuang", 0)
  --[[
  if player:getMark(skel.name .. "_reverse") > 0 then
    player.room:setPlayerMark(player, "@@lb__yuekuang_reverse", 1)
  end
  --]]
  player.room:setPlayerMark(player, "lb__yuekuang_reverse", 0)
end)

return skel